package references

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
	"jvm/nzpJvm/runtime_area/heap"
)

// 调用静态方法的指令
type INVOKE_STATIC struct{ base.Index16Instruction }

func (self *INVOKE_STATIC) Execute(frame *runtime_area.Frame) {
	constantPool := frame.Method().Class().ConstantPool()
	methodRef := constantPool.GetConstant(self.Index).(*heap.MethodRef)
	method := methodRef.ResolveMethod()
	class := method.Class()
	// 如果类还没有被初始化，先进行初始化
	if !class.InitStart(){
		// 中断当前指令，转而去执行clinit方法，所以当前栈帧要回退到上一条指令。clinit方法返回时，要重新执行这条指令
		// 其实这个clinit方法，可以在类加载的时候就执行，包括在jvm规范中描述的都是在类加载的时候执行
		// 不过Hotspot虚拟机是在实际用到的时候才执行clinit方法
		frame.RevertNextPc()
		base.InitClass(frame.Thread(),class)
		return
	}

	if !method.IsStatic() {
		panic("java.lang.IncompatibleClassChangeError")
	}
	base.InvokeMethod(frame, method)
}
